#ifndef _MATERIAU_H
#define _MATERIAU_H

#include "Noyau/Couleur.hpp"

#include "Algebre/Coord.hpp"

/**
 * Permet de catégoriser les différents types de matériau.
 */
enum TypeMateriau
  {
    tCouleurSimple, /**< Juste une Couleur unie. */
    tPerlin,        /**< Un bruit de Perlin est appliqué sur la
		       normale. @todo Il faut redéfinir cette
		       catégorie. */
    tCarreaux,      /**< Un damier formé bicolore. */
    tTexture,       /**< Une texture chargée depuis une image. */
    tMarbre,        /**< Un effet marbré obtenu avec deux couleurs.*/
    tMultiCouleurs, /**< Un mélange de \f$n\f$ couleurs à partir d'un
		       bruit de Perlin. */
    tEffetBois      /**< Un effet de bois. */
  };

/**
 * Classe implémentant les propriétés optiques d'un matériau. On
 * définit une Couleur, le coefficient de réflexion, l'indice de
 * réfraction, la "régularité" (càd la tendance à diffuser de la
 * lumière) et la transparence.
 *
 * @author Jean-Marc Comby + Romain Dequesne
 * @author Johan "Solo" Luisier
 *
 * @date 25 Mars 2004
 */
class Materiau
{
 public:
  //les methodes
  //constructeur par defaut
  //constructeur
  Materiau(const double& refl, const double& trans, const double& indice,
	   const double& reg, const double& bruit,
	   const Couleur& c = Couleur( 0, 0, 0 ));
  Materiau(const double& refl = 0., const double& trans = 0.,
	   const double& indice = 1., const double& reg = 0.,
	   const Couleur& c = Couleur( 0, 0, 0 )); // constructeur normal par defaut bruit=0
  Materiau( const double& refl, const double& trans, const double& indice,
	    const double& reg, const double& bruit, const TypeMateriau& type );
  //destructeur
  virtual ~Materiau();
  //les get
  const double& reflexivite() const;
  const double& transparence() const;
  const double& indice() const;
  const double& regularite() const;
  const double& bruit() const;
  virtual Couleur couleur(const Coord &) = 0;
  void setReflexivite( const double& reflexivite );
  void setTransparence( const double& transparence );
  void setIndice( const double& indice );
  void setRegularite( const double& regularite );
  void setBruit( const double& bruit );
  //methodes qui envoie false si l objet est opaque
  bool estTransparent() const;
  //fonctions de renvoi de couleur
  Couleur lumiereDiffusee( const Couleur& c, const double& angle,
			   const Coord &inters );
  Couleur& lumiereReflechie(Couleur&);
  Couleur lumiereRefractee( const Couleur& c, const Coord &inters );
  const TypeMateriau& type() const;
 protected:
  //les attributs
  /**
   * Coefficient de réflexion. Le coefficient est compris dans
   * l'intervalle \f$\left[ 0, 1 \right] \f$, plus sa valeur est grande
   * et plus le Materiau réfléchit.
   */
  double Reflexivite;
  /**
   * Transparence de l'objet. Le coefficient est compris dans
   * l'intervalle \f$ \left[ 0, 1 \right] \f$, plus sa valeur est
   * grande et plus le Materiau est transparent.
   */
  double Transparence;
  /**
   * Indice de réfraction de l'objet. Normalement un indice de
   * réfraction doit être plus grand que 1, mais ici on autorise des
   * indices de réfraction dans l'intervalle \f$ \left[ 0, 100 \right]
   * \f$.
   */
  double Indice;
  /**
   * Coefficient permettant de régler la diffusion de la lumière
   * incidente par le Materiau. Le coefficient est compris dans
   * l'intervalle \f$ \left[ 0, 1 \right] \f$, plus sa valeur est
   * grande et plus le Materiau aura tendance à diffuser la lumière.
   */
  double Regularite; //0.0 eqivaut a un objet opaque
  /**
   * Permet de générer du bruit sur la surface (pour le moment bouge
   * la normale uniquement). Le bruit est compris dans l'intervalle
   * \f$ \left[ 0, 1 \right] \f$.
   */
  double Bruit; // permet de generer un bruit sur la surface (0 pas de bruit, 1 bcp de bruit)
  /*
   * Couleur du Materiau.
   */
  //Couleur Color;
  /**
   * Stocke le type du Materiau.
   */
  TypeMateriau Type;
};
#endif
